#ifndef SYS_INTERRUPT_H
#define SYS_INTERRUPT_H

#include <yonex/types.h>
#include <sys/global.h>
#include <stdbool.h>

#define IDT_SIZE    256

#define IRQ_CLOCK       0x20    // 时钟
#define IRQ_KEYBOARD    0x21    // 键盘
#define IRQ_CASCADE     0x22    // 8259A从片
#define IRQ_SERIAL_2    0x23    // 串口2
#define IRQ_SERIAL_1    0x24    // 串口1
#define IRQ_PARALLEL_2  0x25    // 并口2
#define IRQ_FLOPPY      0x26    // 软盘
#define IRQ_PARALLEL_1  0x27    // 并口1
#define IRQ_RTC         0x28    // 实时时钟
#define IRQ_REDIRECT    0x29    // 重定向 IRQ2
// IRQ 10~11 保留
#define IRQ_MOUSE       0x2c    // 鼠标
#define IRQ_MATH        0x2d    // 协处理器 x87
#define IRQ_DISK        0x2e    // ATA 硬盘第一通道
#define IRQ_DISK_2      0x2f    // ATA 硬盘第二通道

typedef void *handler_t;

typedef struct
{
    u16 offset0;        // 段内偏移0~15位
    selector_t selector;// 代码段选择子
    u8 ist : 3;         // Interrupt Stack Table
    u8 reserved0 : 5;   // 保留
    u8 type : 4;        // 任务门/中断门/陷阱门/调用门
    u8 segment : 1;     // segment = 0 表示系统段
    u8 DPL : 2;         // 描述特权级
    u8 present : 1;     // 是否有效
    u16 offset1;        // 段内偏移16~31位
    u32 offset2;        // 段内偏移32~63位
    u32 reserved1;      // 保留
} __attribute__((packed)) gate_t;

void interrupt_init();
void send_eoi(int vector);
void set_interrupt_handler(int vector, handler_t handler);
void set_interrupt_mask(int vector, bool enable);

#endif
